/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.WebIDE.ejb.sessions;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;
import javax.transaction.UserTransaction;
import org.WebIDE.ejb.entities.*;
import org.WebIDE.ejb.sessions.exceptions.*;

/**
 *
 * @author huy
 */
@Stateless
public class UsersFacade implements UsersFacadeLocal, UsersFacadeRemote {
    @PersistenceContext(unitName = "WebIDE-ejbPU")
    private EntityManager _em;
    @PersistenceUnit(unitName = "WebIDE-ejbPU")
    private EntityManagerFactory emf = null;
    @Resource
    private UserTransaction utx = null;
    /*
    public void create(Users users) {
    em.persist(users);
    }

    public void edit(Users users) {
    em.merge(users);
    }
     */

    public void remove(Users users) {
        _em.remove(_em.merge(users));
    }

    public Users find(Object id) {
        return _em.find(Users.class, id);
    }


    public List<Users> findAll() {
        return _em.createQuery("select object(o) from Users as o").getResultList();
    }

    private EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Users users) throws PreexistingEntityException, RollbackFailureException, Exception {
        if (users.getGroupsCollection() == null) {
            users.setGroupsCollection(new ArrayList<Groups>());
        }
        if (users.getProjectsCollection() == null) {
            users.setProjectsCollection(new ArrayList<Projects>());
        }
        if (users.getTopicsCollection() == null) {
            users.setTopicsCollection(new ArrayList<Topics>());
        }
        if (users.getRepliesCollection() == null) {
            users.setRepliesCollection(new ArrayList<Replies>());
        }
        if (users.getMessagesCollection() == null) {
            users.setMessagesCollection(new ArrayList<Messages>());
        }
        EntityManager em = null;
        try {
            //utx.begin();
            em = getEntityManager();
            Collection<Groups> attachedGroupNameCollection = new ArrayList<Groups>();
            for (Groups groupNameCollectionGroupsToAttach : users.getGroupsCollection()) {
                groupNameCollectionGroupsToAttach = em.getReference(groupNameCollectionGroupsToAttach.getClass(), groupNameCollectionGroupsToAttach.getGroupName());
                attachedGroupNameCollection.add(groupNameCollectionGroupsToAttach);
            }
            users.setGroupsCollection(attachedGroupNameCollection);
            Collection<Projects> attachedProjectsCollection = new ArrayList<Projects>();
            for (Projects projectsCollectionProjectsToAttach : users.getProjectsCollection()) {
                projectsCollectionProjectsToAttach = em.getReference(projectsCollectionProjectsToAttach.getClass(), projectsCollectionProjectsToAttach.getId());
                attachedProjectsCollection.add(projectsCollectionProjectsToAttach);
            }
            users.setProjectsCollection(attachedProjectsCollection);
            Collection<Topics> attachedTopicsCollection = new ArrayList<Topics>();
            for (Topics topicsCollectionTopicsToAttach : users.getTopicsCollection()) {
                topicsCollectionTopicsToAttach = em.getReference(topicsCollectionTopicsToAttach.getClass(), topicsCollectionTopicsToAttach.getId());
                attachedTopicsCollection.add(topicsCollectionTopicsToAttach);
            }
            users.setTopicsCollection(attachedTopicsCollection);
            Collection<Replies> attachedRepliesCollection = new ArrayList<Replies>();
            for (Replies repliesCollectionRepliesToAttach : users.getRepliesCollection()) {
                repliesCollectionRepliesToAttach = em.getReference(repliesCollectionRepliesToAttach.getClass(), repliesCollectionRepliesToAttach.getId());
                attachedRepliesCollection.add(repliesCollectionRepliesToAttach);
            }
            users.setRepliesCollection(attachedRepliesCollection);
            Collection<Messages> attachedMessagesCollection = new ArrayList<Messages>();
            for (Messages messagesCollectionMessagesToAttach : users.getMessagesCollection()) {
                messagesCollectionMessagesToAttach = em.getReference(messagesCollectionMessagesToAttach.getClass(), messagesCollectionMessagesToAttach.getId());
                attachedMessagesCollection.add(messagesCollectionMessagesToAttach);
            }
            users.setMessagesCollection(attachedMessagesCollection);
            em.persist(users);
            for (Groups groupNameCollectionGroups : users.getGroupsCollection()) {
                groupNameCollectionGroups.getUsersCollection().add(users);
                groupNameCollectionGroups = em.merge(groupNameCollectionGroups);
            }
            for (Projects projectsCollectionProjects : users.getProjectsCollection()) {
                Users oldUserNameOfProjectsCollectionProjects = projectsCollectionProjects.getUserName();
                projectsCollectionProjects.setUserName(users);
                projectsCollectionProjects = em.merge(projectsCollectionProjects);
                if (oldUserNameOfProjectsCollectionProjects != null) {
                    oldUserNameOfProjectsCollectionProjects.getProjectsCollection().remove(projectsCollectionProjects);
                    oldUserNameOfProjectsCollectionProjects = em.merge(oldUserNameOfProjectsCollectionProjects);
                }
            }
            for (Topics topicsCollectionTopics : users.getTopicsCollection()) {
                Users oldUserNameOfTopicsCollectionTopics = topicsCollectionTopics.getUserName();
                topicsCollectionTopics.setUserName(users);
                topicsCollectionTopics = em.merge(topicsCollectionTopics);
                if (oldUserNameOfTopicsCollectionTopics != null) {
                    oldUserNameOfTopicsCollectionTopics.getTopicsCollection().remove(topicsCollectionTopics);
                    oldUserNameOfTopicsCollectionTopics = em.merge(oldUserNameOfTopicsCollectionTopics);
                }
            }
            for (Replies repliesCollectionReplies : users.getRepliesCollection()) {
                Users oldUserNameOfRepliesCollectionReplies = repliesCollectionReplies.getUserName();
                repliesCollectionReplies.setUserName(users);
                repliesCollectionReplies = em.merge(repliesCollectionReplies);
                if (oldUserNameOfRepliesCollectionReplies != null) {
                    oldUserNameOfRepliesCollectionReplies.getRepliesCollection().remove(repliesCollectionReplies);
                    oldUserNameOfRepliesCollectionReplies = em.merge(oldUserNameOfRepliesCollectionReplies);
                }
            }
            for (Messages messagesCollectionMessages : users.getMessagesCollection()) {
                Users oldUserNameOfMessagesCollectionMessages = messagesCollectionMessages.getUserName();
                messagesCollectionMessages.setUserName(users);
                messagesCollectionMessages = em.merge(messagesCollectionMessages);
                if (oldUserNameOfMessagesCollectionMessages != null) {
                    oldUserNameOfMessagesCollectionMessages.getMessagesCollection().remove(messagesCollectionMessages);
                    oldUserNameOfMessagesCollectionMessages = em.merge(oldUserNameOfMessagesCollectionMessages);
                }
            }
            //utx.commit();
        } catch (Exception ex) {
            try {
                //utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            if (findUsers(users.getUserName()) != null) {
                throw new PreexistingEntityException("Users " + users + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Users users) throws NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            //utx.begin();
            em = getEntityManager();
            Users persistentUsers = em.find(Users.class, users.getUserName());
            Collection<Groups> groupNameCollectionOld = persistentUsers.getGroupsCollection();
            Collection<Groups> groupNameCollectionNew = users.getGroupsCollection();
            Collection<Projects> projectsCollectionOld = persistentUsers.getProjectsCollection();
            Collection<Projects> projectsCollectionNew = users.getProjectsCollection();
            Collection<Topics> topicsCollectionOld = persistentUsers.getTopicsCollection();
            Collection<Topics> topicsCollectionNew = users.getTopicsCollection();
            Collection<Replies> repliesCollectionOld = persistentUsers.getRepliesCollection();
            Collection<Replies> repliesCollectionNew = users.getRepliesCollection();
            Collection<Messages> messagesCollectionOld = persistentUsers.getMessagesCollection();
            Collection<Messages> messagesCollectionNew = users.getMessagesCollection();
            Collection<Groups> attachedGroupNameCollectionNew = new ArrayList<Groups>();
            for (Groups groupNameCollectionNewGroupsToAttach : groupNameCollectionNew) {
                groupNameCollectionNewGroupsToAttach = em.getReference(groupNameCollectionNewGroupsToAttach.getClass(), groupNameCollectionNewGroupsToAttach.getGroupName());
                attachedGroupNameCollectionNew.add(groupNameCollectionNewGroupsToAttach);
            }
            groupNameCollectionNew = attachedGroupNameCollectionNew;
            users.setGroupsCollection(groupNameCollectionNew);
            Collection<Projects> attachedProjectsCollectionNew = new ArrayList<Projects>();
            for (Projects projectsCollectionNewProjectsToAttach : projectsCollectionNew) {
                projectsCollectionNewProjectsToAttach = em.getReference(projectsCollectionNewProjectsToAttach.getClass(), projectsCollectionNewProjectsToAttach.getId());
                attachedProjectsCollectionNew.add(projectsCollectionNewProjectsToAttach);
            }
            projectsCollectionNew = attachedProjectsCollectionNew;
            users.setProjectsCollection(projectsCollectionNew);
            Collection<Topics> attachedTopicsCollectionNew = new ArrayList<Topics>();
            for (Topics topicsCollectionNewTopicsToAttach : topicsCollectionNew) {
                topicsCollectionNewTopicsToAttach = em.getReference(topicsCollectionNewTopicsToAttach.getClass(), topicsCollectionNewTopicsToAttach.getId());
                attachedTopicsCollectionNew.add(topicsCollectionNewTopicsToAttach);
            }
            topicsCollectionNew = attachedTopicsCollectionNew;
            users.setTopicsCollection(topicsCollectionNew);
            Collection<Replies> attachedRepliesCollectionNew = new ArrayList<Replies>();
            for (Replies repliesCollectionNewRepliesToAttach : repliesCollectionNew) {
                repliesCollectionNewRepliesToAttach = em.getReference(repliesCollectionNewRepliesToAttach.getClass(), repliesCollectionNewRepliesToAttach.getId());
                attachedRepliesCollectionNew.add(repliesCollectionNewRepliesToAttach);
            }
            repliesCollectionNew = attachedRepliesCollectionNew;
            users.setRepliesCollection(repliesCollectionNew);
            Collection<Messages> attachedMessagesCollectionNew = new ArrayList<Messages>();
            for (Messages messagesCollectionNewMessagesToAttach : messagesCollectionNew) {
                messagesCollectionNewMessagesToAttach = em.getReference(messagesCollectionNewMessagesToAttach.getClass(), messagesCollectionNewMessagesToAttach.getId());
                attachedMessagesCollectionNew.add(messagesCollectionNewMessagesToAttach);
            }
            messagesCollectionNew = attachedMessagesCollectionNew;
            users.setMessagesCollection(messagesCollectionNew);
            users = em.merge(users);
            for (Groups groupNameCollectionOldGroups : groupNameCollectionOld) {
                if (!groupNameCollectionNew.contains(groupNameCollectionOldGroups)) {
                    groupNameCollectionOldGroups.getUsersCollection().remove(users);
                    groupNameCollectionOldGroups = em.merge(groupNameCollectionOldGroups);
                }
            }
            for (Groups groupNameCollectionNewGroups : groupNameCollectionNew) {
                if (!groupNameCollectionOld.contains(groupNameCollectionNewGroups)) {
                    groupNameCollectionNewGroups.getUsersCollection().add(users);
                    groupNameCollectionNewGroups = em.merge(groupNameCollectionNewGroups);
                }
            }
            for (Projects projectsCollectionOldProjects : projectsCollectionOld) {
                if (!projectsCollectionNew.contains(projectsCollectionOldProjects)) {
                    projectsCollectionOldProjects.setUserName(null);
                    projectsCollectionOldProjects = em.merge(projectsCollectionOldProjects);
                }
            }
            for (Projects projectsCollectionNewProjects : projectsCollectionNew) {
                if (!projectsCollectionOld.contains(projectsCollectionNewProjects)) {
                    Users oldUserNameOfProjectsCollectionNewProjects = projectsCollectionNewProjects.getUserName();
                    projectsCollectionNewProjects.setUserName(users);
                    projectsCollectionNewProjects = em.merge(projectsCollectionNewProjects);
                    if (oldUserNameOfProjectsCollectionNewProjects != null && !oldUserNameOfProjectsCollectionNewProjects.equals(users)) {
                        oldUserNameOfProjectsCollectionNewProjects.getProjectsCollection().remove(projectsCollectionNewProjects);
                        oldUserNameOfProjectsCollectionNewProjects = em.merge(oldUserNameOfProjectsCollectionNewProjects);
                    }
                }
            }
            for (Topics topicsCollectionOldTopics : topicsCollectionOld) {
                if (!topicsCollectionNew.contains(topicsCollectionOldTopics)) {
                    topicsCollectionOldTopics.setUserName(null);
                    topicsCollectionOldTopics = em.merge(topicsCollectionOldTopics);
                }
            }
            for (Topics topicsCollectionNewTopics : topicsCollectionNew) {
                if (!topicsCollectionOld.contains(topicsCollectionNewTopics)) {
                    Users oldUserNameOfTopicsCollectionNewTopics = topicsCollectionNewTopics.getUserName();
                    topicsCollectionNewTopics.setUserName(users);
                    topicsCollectionNewTopics = em.merge(topicsCollectionNewTopics);
                    if (oldUserNameOfTopicsCollectionNewTopics != null && !oldUserNameOfTopicsCollectionNewTopics.equals(users)) {
                        oldUserNameOfTopicsCollectionNewTopics.getTopicsCollection().remove(topicsCollectionNewTopics);
                        oldUserNameOfTopicsCollectionNewTopics = em.merge(oldUserNameOfTopicsCollectionNewTopics);
                    }
                }
            }
            for (Replies repliesCollectionOldReplies : repliesCollectionOld) {
                if (!repliesCollectionNew.contains(repliesCollectionOldReplies)) {
                    repliesCollectionOldReplies.setUserName(null);
                    repliesCollectionOldReplies = em.merge(repliesCollectionOldReplies);
                }
            }
            for (Replies repliesCollectionNewReplies : repliesCollectionNew) {
                if (!repliesCollectionOld.contains(repliesCollectionNewReplies)) {
                    Users oldUserNameOfRepliesCollectionNewReplies = repliesCollectionNewReplies.getUserName();
                    repliesCollectionNewReplies.setUserName(users);
                    repliesCollectionNewReplies = em.merge(repliesCollectionNewReplies);
                    if (oldUserNameOfRepliesCollectionNewReplies != null && !oldUserNameOfRepliesCollectionNewReplies.equals(users)) {
                        oldUserNameOfRepliesCollectionNewReplies.getRepliesCollection().remove(repliesCollectionNewReplies);
                        oldUserNameOfRepliesCollectionNewReplies = em.merge(oldUserNameOfRepliesCollectionNewReplies);
                    }
                }
            }
            for (Messages messagesCollectionOldMessages : messagesCollectionOld) {
                if (!messagesCollectionNew.contains(messagesCollectionOldMessages)) {
                    messagesCollectionOldMessages.setUserName(null);
                    messagesCollectionOldMessages = em.merge(messagesCollectionOldMessages);
                }
            }
            for (Messages messagesCollectionNewMessages : messagesCollectionNew) {
                if (!messagesCollectionOld.contains(messagesCollectionNewMessages)) {
                    Users oldUserNameOfMessagesCollectionNewMessages = messagesCollectionNewMessages.getUserName();
                    messagesCollectionNewMessages.setUserName(users);
                    messagesCollectionNewMessages = em.merge(messagesCollectionNewMessages);
                    if (oldUserNameOfMessagesCollectionNewMessages != null && !oldUserNameOfMessagesCollectionNewMessages.equals(users)) {
                        oldUserNameOfMessagesCollectionNewMessages.getMessagesCollection().remove(messagesCollectionNewMessages);
                        oldUserNameOfMessagesCollectionNewMessages = em.merge(oldUserNameOfMessagesCollectionNewMessages);
                    }
                }
            }
            //utx.commit();
        } catch (Exception ex) {
            try {
                //utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = users.getUserName();
                if (findUsers(id) == null) {
                    throw new NonexistentEntityException("The users with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(String id) throws NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            //utx.begin();
            em = getEntityManager();
            Users users;
            try {
                users = em.getReference(Users.class, id);
                users.getUserName();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The users with id " + id + " no longer exists.", enfe);
            }
            Collection<Groups> groupNameCollection = users.getGroupsCollection();
            for (Groups groupNameCollectionGroups : groupNameCollection) {
                groupNameCollectionGroups.getUsersCollection().remove(users);
                groupNameCollectionGroups = em.merge(groupNameCollectionGroups);
            }
            Collection<Projects> projectsCollection = users.getProjectsCollection();
            for (Projects projectsCollectionProjects : projectsCollection) {
                projectsCollectionProjects.setUserName(null);
                projectsCollectionProjects = em.merge(projectsCollectionProjects);
            }
            Collection<Topics> topicsCollection = users.getTopicsCollection();
            for (Topics topicsCollectionTopics : topicsCollection) {
                topicsCollectionTopics.setUserName(null);
                topicsCollectionTopics = em.merge(topicsCollectionTopics);
            }
            Collection<Replies> repliesCollection = users.getRepliesCollection();
            for (Replies repliesCollectionReplies : repliesCollection) {
                repliesCollectionReplies.setUserName(null);
                repliesCollectionReplies = em.merge(repliesCollectionReplies);
            }
            Collection<Messages> messagesCollection = users.getMessagesCollection();
            for (Messages messagesCollectionMessages : messagesCollection) {
                messagesCollectionMessages.setUserName(null);
                messagesCollectionMessages = em.merge(messagesCollectionMessages);
            }
            em.remove(users);
            //utx.commit();
        } catch (Exception ex) {
            try {
                //utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Users> findUsersEntities() {
        return findUsersEntities(true, -1, -1);
    }

    public List<Users> findUsersEntities(int maxResults, int firstResult) {
        return findUsersEntities(false, maxResults, firstResult);
    }

    private List<Users> findUsersEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Users as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
           em.close();
        }
    }

    public Users findUsers(String id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Users.class, id);
         
        } finally {
            em.close();
        }
    }

    public int getUsersCount() {
        EntityManager em = getEntityManager();
        try {
            return ((Long) _em.createQuery("SELECT COUNT(o) FROM Users AS o").getSingleResult()).intValue();
            //return ((Long) _em.createNamedQuery("Users.count").getSingleResult()).intValue();
            //return 9;
        } finally {
            em.close();
        }
    }
}
